Check for XFIXES extension.
authorMatthias Clasen <mclasen@redhat.com>
Tue, 18 May 2004 20:56:54 +0000 (20:56 +0000)
committerMatthias Clasen <matthiasc@src.gnome.org>
Tue, 18 May 2004 20:56:54 +0000 (20:56 +0000)
2004-05-18  Matthias Clasen  <mclasen@redhat.com>

* configure.in: Check for XFIXES extension.

* gdk/x11/gdkdisplay-x11.h (struct _GdkDisplayX11): Add
a gboolean have_xfixes member.

* gdk/x11/gdkdisplay-x11.c (gdk_display_open): Register
XFIXES events and set have_xfixes.

* gdk/gdkevents.h (GdkEventType): Add GDK_OWNER_CHANGE.
(GdkEventOwnerChange): New event struct for owner change events.
(GdkOwnerChange): New enum for the reason field of GdkEventOwnerChange.

* gdk/x11/gdkevents-x11.c (gdk_event_translate): Translate
XFixesSelectionNotify events into GdkEventOwnerChange events.

* gdk/gdkdisplay.h:
* gdk/x11/gdkdisplay-x11.c (gdk_display_supports_selection_notification):
(gdk_display_request_selection_notification): New api
to support selection ownership notification.

* gtk/gtkclipboard.h:
* gtk/gtkclipboard.c (_gtk_clipboard_handle_event): New private
api to handle owner change events.
(clipboard_peek): Refactored out the body of
gtk_clipboard_get_for_display() for use in _gtk_clipboard_handle_event().

* gtk/gtkmain.c (gtk_main_do_event): Handle GDK_OWNER_CHANGE events
by calling _gtk_clipboard_handle_event().

18 files changed:
ChangeLog
ChangeLog.pre-2-10
ChangeLog.pre-2-6
ChangeLog.pre-2-8
docs/reference/ChangeLog
docs/reference/gdk-pixbuf/tmpl/module_interface.sgml
docs/reference/gdk/gdk-sections.txt
docs/reference/gdk/tmpl/events.sgml
docs/reference/gdk/tmpl/gdkdisplay.sgml
docs/reference/gtk/tmpl/gtkenums.sgml
gdk/gdkdisplay.h
gdk/gdkevents.h
gdk/x11/gdkdisplay-x11.c
gdk/x11/gdkdisplay-x11.h
gdk/x11/gdkevents-x11.c
gtk/gtkclipboard.c
gtk/gtkclipboard.h
gtk/gtkmain.c

index f50fab73b89b190b5efdca1b8674d182cbe60f6a..fd8cdd184719c842f2a0e95d985a397d0da0be88 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,34 @@
+2004-05-18  Matthias Clasen  <mclasen@redhat.com>
+
+       * configure.in: Check for XFIXES extension.
+
+       * gdk/x11/gdkdisplay-x11.h (struct _GdkDisplayX11): Add 
+       a gboolean have_xfixes member.
+
+       * gdk/x11/gdkdisplay-x11.c (gdk_display_open): Register
+       XFIXES events and set have_xfixes.
+
+       * gdk/gdkevents.h (GdkEventType): Add GDK_OWNER_CHANGE.
+       (GdkEventOwnerChange): New event struct for owner change events.
+       (GdkOwnerChange): New enum for the reason field of GdkEventOwnerChange.
+       
+       * gdk/x11/gdkevents-x11.c (gdk_event_translate): Translate 
+       XFixesSelectionNotify events into GdkEventOwnerChange events.
+       
+       * gdk/gdkdisplay.h:
+       * gdk/x11/gdkdisplay-x11.c (gdk_display_supports_selection_notification):
+       (gdk_display_request_selection_notification): New api 
+       to support selection ownership notification.
+
+       * gtk/gtkclipboard.h:
+       * gtk/gtkclipboard.c (_gtk_clipboard_handle_event): New private
+       api to handle owner change events.
+       (clipboard_peek): Refactored out the body of 
+       gtk_clipboard_get_for_display() for use in _gtk_clipboard_handle_event().
+
+       * gtk/gtkmain.c (gtk_main_do_event): Handle GDK_OWNER_CHANGE events
+       by calling _gtk_clipboard_handle_event().
+
 2004-05-18  Matthias Clasen  <mclasen@redhat.com>
 
        * gtk/gtkintl.h: Include glib/gi18n-lib.h and only define
index f50fab73b89b190b5efdca1b8674d182cbe60f6a..fd8cdd184719c842f2a0e95d985a397d0da0be88 100644 (file)
@@ -1,3 +1,34 @@
+2004-05-18  Matthias Clasen  <mclasen@redhat.com>
+
+       * configure.in: Check for XFIXES extension.
+
+       * gdk/x11/gdkdisplay-x11.h (struct _GdkDisplayX11): Add 
+       a gboolean have_xfixes member.
+
+       * gdk/x11/gdkdisplay-x11.c (gdk_display_open): Register
+       XFIXES events and set have_xfixes.
+
+       * gdk/gdkevents.h (GdkEventType): Add GDK_OWNER_CHANGE.
+       (GdkEventOwnerChange): New event struct for owner change events.
+       (GdkOwnerChange): New enum for the reason field of GdkEventOwnerChange.
+       
+       * gdk/x11/gdkevents-x11.c (gdk_event_translate): Translate 
+       XFixesSelectionNotify events into GdkEventOwnerChange events.
+       
+       * gdk/gdkdisplay.h:
+       * gdk/x11/gdkdisplay-x11.c (gdk_display_supports_selection_notification):
+       (gdk_display_request_selection_notification): New api 
+       to support selection ownership notification.
+
+       * gtk/gtkclipboard.h:
+       * gtk/gtkclipboard.c (_gtk_clipboard_handle_event): New private
+       api to handle owner change events.
+       (clipboard_peek): Refactored out the body of 
+       gtk_clipboard_get_for_display() for use in _gtk_clipboard_handle_event().
+
+       * gtk/gtkmain.c (gtk_main_do_event): Handle GDK_OWNER_CHANGE events
+       by calling _gtk_clipboard_handle_event().
+
 2004-05-18  Matthias Clasen  <mclasen@redhat.com>
 
        * gtk/gtkintl.h: Include glib/gi18n-lib.h and only define
index f50fab73b89b190b5efdca1b8674d182cbe60f6a..fd8cdd184719c842f2a0e95d985a397d0da0be88 100644 (file)
@@ -1,3 +1,34 @@
+2004-05-18  Matthias Clasen  <mclasen@redhat.com>
+
+       * configure.in: Check for XFIXES extension.
+
+       * gdk/x11/gdkdisplay-x11.h (struct _GdkDisplayX11): Add 
+       a gboolean have_xfixes member.
+
+       * gdk/x11/gdkdisplay-x11.c (gdk_display_open): Register
+       XFIXES events and set have_xfixes.
+
+       * gdk/gdkevents.h (GdkEventType): Add GDK_OWNER_CHANGE.
+       (GdkEventOwnerChange): New event struct for owner change events.
+       (GdkOwnerChange): New enum for the reason field of GdkEventOwnerChange.
+       
+       * gdk/x11/gdkevents-x11.c (gdk_event_translate): Translate 
+       XFixesSelectionNotify events into GdkEventOwnerChange events.
+       
+       * gdk/gdkdisplay.h:
+       * gdk/x11/gdkdisplay-x11.c (gdk_display_supports_selection_notification):
+       (gdk_display_request_selection_notification): New api 
+       to support selection ownership notification.
+
+       * gtk/gtkclipboard.h:
+       * gtk/gtkclipboard.c (_gtk_clipboard_handle_event): New private
+       api to handle owner change events.
+       (clipboard_peek): Refactored out the body of 
+       gtk_clipboard_get_for_display() for use in _gtk_clipboard_handle_event().
+
+       * gtk/gtkmain.c (gtk_main_do_event): Handle GDK_OWNER_CHANGE events
+       by calling _gtk_clipboard_handle_event().
+
 2004-05-18  Matthias Clasen  <mclasen@redhat.com>
 
        * gtk/gtkintl.h: Include glib/gi18n-lib.h and only define
index f50fab73b89b190b5efdca1b8674d182cbe60f6a..fd8cdd184719c842f2a0e95d985a397d0da0be88 100644 (file)
@@ -1,3 +1,34 @@
+2004-05-18  Matthias Clasen  <mclasen@redhat.com>
+
+       * configure.in: Check for XFIXES extension.
+
+       * gdk/x11/gdkdisplay-x11.h (struct _GdkDisplayX11): Add 
+       a gboolean have_xfixes member.
+
+       * gdk/x11/gdkdisplay-x11.c (gdk_display_open): Register
+       XFIXES events and set have_xfixes.
+
+       * gdk/gdkevents.h (GdkEventType): Add GDK_OWNER_CHANGE.
+       (GdkEventOwnerChange): New event struct for owner change events.
+       (GdkOwnerChange): New enum for the reason field of GdkEventOwnerChange.
+       
+       * gdk/x11/gdkevents-x11.c (gdk_event_translate): Translate 
+       XFixesSelectionNotify events into GdkEventOwnerChange events.
+       
+       * gdk/gdkdisplay.h:
+       * gdk/x11/gdkdisplay-x11.c (gdk_display_supports_selection_notification):
+       (gdk_display_request_selection_notification): New api 
+       to support selection ownership notification.
+
+       * gtk/gtkclipboard.h:
+       * gtk/gtkclipboard.c (_gtk_clipboard_handle_event): New private
+       api to handle owner change events.
+       (clipboard_peek): Refactored out the body of 
+       gtk_clipboard_get_for_display() for use in _gtk_clipboard_handle_event().
+
+       * gtk/gtkmain.c (gtk_main_do_event): Handle GDK_OWNER_CHANGE events
+       by calling _gtk_clipboard_handle_event().
+
 2004-05-18  Matthias Clasen  <mclasen@redhat.com>
 
        * gtk/gtkintl.h: Include glib/gi18n-lib.h and only define
index c49ca30bd4599f6f2eb7a2e4792e46897c57a8d6..e2cb1dea253740bd63e6b31c2c482cea045bfbca 100644 (file)
@@ -1,3 +1,8 @@
+2004-05-18  Matthias Clasen  <mclasen@redhat.com>
+
+       * gdk/gdk-sections.txt: Add gdk_display_supports_selection_notification
+       and gdk_display_request_selection_notification.
+
 2004-05-14  Matthias Clasen  <mclasen@redhat.com>
 
        * gtk/tree_widget.sgml: Minor update.
index 794384d6efe3a0f11404c9893bd04aeba4f75832..94e928bd971ece9e7f76b4321a914da5baa35e1f 100644 (file)
@@ -129,6 +129,15 @@ They are not covered by the same stability guarantees as the regular
 @Returns: 
 
 
+<!-- ##### FUNCTION gdk_pixbuf_format_is_scalable ##### -->
+<para>
+
+</para>
+
+@format: 
+@Returns: 
+
+
 <!-- ##### STRUCT GdkPixbufFormat ##### -->
 <para>
 A #GdkPixbufFormat contains information about the image format accepted by a
@@ -153,6 +162,7 @@ operations.
 </para>
 
 @GDK_PIXBUF_FORMAT_WRITABLE: the module can write out images in the format.
+@GDK_PIXBUF_FORMAT_SCALABLE: 
 @Since: 2.2
 
 <!-- ##### STRUCT GdkPixbufModulePattern ##### -->
index 92a508d608faae82ee06323ae2d3f99e5872bb82..a9c6fe44df89ea8a433dbe10fec0c8f2320cb4df 100644 (file)
@@ -145,6 +145,8 @@ gdk_display_supports_cursor_alpha
 gdk_display_get_default_cursor_size
 gdk_display_get_maximal_cursor_size
 gdk_display_get_default_group
+gdk_display_supports_selection_notification
+gdk_display_request_selection_notification
 
 <SUBSECTION Standard>
 GDK_DISPLAY_OBJECT
index caabb4411dff23b1d181e564e1d247169dafcd02..4baccc895d0f3711ce7406aa2af44492e052ba34 100644 (file)
@@ -84,6 +84,7 @@ when parts of a drawable were copied. This is not very useful.
 @GDK_SCROLL: 
 @GDK_WINDOW_STATE: 
 @GDK_SETTING: 
+@GDK_OWNER_CHANGE: 
 
 <!-- ##### ENUM GdkEventMask ##### -->
 <para>
index a7cf8e857c65e1e5146d8912206b6439a3f51412..69637705d0f5e7ebfddbf65b62e8abc8d9ca7015 100644 (file)
@@ -324,3 +324,22 @@ Applications should never have any reason to use this facility
 @Returns: 
 
 
+<!-- ##### FUNCTION gdk_display_supports_selection_notification ##### -->
+<para>
+
+</para>
+
+@display: 
+@Returns: 
+
+
+<!-- ##### FUNCTION gdk_display_request_selection_notification ##### -->
+<para>
+
+</para>
+
+@display: 
+@selection: 
+@Returns: 
+
+
index c37882d0f2364a275ead57909f8fee8226908a46..1a58ba7b7c21f6142e94f8eed76eb73bd987f62c 100644 (file)
@@ -336,14 +336,14 @@ Indicated the relief to be drawn around a #GtkButton.
 </para>
 
 @GTK_SELECTION_NONE: No selection is possible.
-@GTK_SELECTION_SINGLE: Zero or one element may be selected. 
+@GTK_SELECTION_SINGLE: Zero or one element may be selected.
 @GTK_SELECTION_BROWSE: Exactly one element is always selected 
    (this can be false after you have changed the selection mode).
 @GTK_SELECTION_MULTIPLE: Any number of elements may be selected. 
    Clicks toggle the state of an item. Any number of elements may be selected. 
    Click-drag selects a range of elements; the Ctrl key may be used to enlarge 
    the selection, and Shift key to select between the focus and the child 
-   pointed to. 
+   pointed to.
 @GTK_SELECTION_EXTENDED: Deprecated, behaves identical to 
    %GTK_SELECTION_MULTIPLE.
 
index 2bbc7eb8e8c206ea038cce067456dc6b9437833f..75c1b9c3ed9cc686a4f9db14fc5141eec22b5939 100644 (file)
@@ -164,6 +164,10 @@ void     gdk_display_get_maximal_cursor_size   (GdkDisplay    *display,
 
 GdkWindow *gdk_display_get_default_group       (GdkDisplay *display); 
 
+gboolean gdk_display_supports_selection_notification (GdkDisplay *display);
+gboolean gdk_display_request_selection_notification  (GdkDisplay *display,
+                                                     GdkAtom     selection);
+
 G_END_DECLS
 
-#endif                         /* __GDK_DISPLAY_H__ */
+#endif /* __GDK_DISPLAY_H__ */
index e7cafb91303dfae61ddabeb0df4a89959abebd51..000775dbf3f6f391f1eac0647e3aeb470ec97220 100644 (file)
@@ -29,6 +29,7 @@ typedef struct _GdkEventCrossing    GdkEventCrossing;
 typedef struct _GdkEventConfigure   GdkEventConfigure;
 typedef struct _GdkEventProperty    GdkEventProperty;
 typedef struct _GdkEventSelection   GdkEventSelection;
+typedef struct _GdkEventOwnerChange GdkEventOwnerChange;
 typedef struct _GdkEventProximity   GdkEventProximity;
 typedef struct _GdkEventClient     GdkEventClient;
 typedef struct _GdkEventDND         GdkEventDND;
@@ -118,7 +119,8 @@ typedef enum
   GDK_NO_EXPOSE                = 30,
   GDK_SCROLL            = 31,
   GDK_WINDOW_STATE      = 32,
-  GDK_SETTING           = 33
+  GDK_SETTING           = 33,
+  GDK_OWNER_CHANGE      = 34
 } GdkEventType;
 
 /* Event masks. (Used to select what types of events a window
@@ -219,6 +221,13 @@ typedef enum
   GDK_SETTING_ACTION_DELETED
 } GdkSettingAction;
 
+typedef enum
+{
+  GDK_OWNER_CHANGE_NEW_OWNER,
+  GDK_OWNER_CHANGE_DESTROY,
+  GDK_OWNER_CHANGE_CLOSE
+} GdkOwnerChange;
+
 struct _GdkEventAny
 {
   GdkEventType type;
@@ -366,6 +375,18 @@ struct _GdkEventSelection
   GdkNativeWindow requestor;
 };
 
+struct _GdkEventOwnerChange
+{
+  GdkEventType type;
+  GdkWindow *window;
+  gint8 send_event;
+  GdkNativeWindow owner;
+  GdkOwnerChange reason;
+  GdkAtom selection;
+  guint32 time;
+  guint32 selection_time;
+};
+
 /* This event type will be used pretty rarely. It only is important
    for XInput aware programs that are drawing their own cursor */
 
@@ -438,6 +459,7 @@ union _GdkEvent
   GdkEventConfigure        configure;
   GdkEventProperty         property;
   GdkEventSelection        selection;
+  GdkEventOwnerChange              owner_change;
   GdkEventProximity        proximity;
   GdkEventClient           client;
   GdkEventDND               dnd;
index a765a063fb763bbfc322ed0fb6d1694772f65af4..66c4766b1879cf620f7df163e4c7c3a6045b12d6 100644 (file)
 #include <X11/XKBlib.h>
 #endif
 
+#ifdef HAVE_XFIXES
+#include <X11/extensions/Xfixes.h>
+#endif
+
 static void                 gdk_display_x11_class_init         (GdkDisplayX11Class *class);
 static void                 gdk_display_x11_dispose            (GObject            *object);
 static void                 gdk_display_x11_finalize           (GObject            *object);
@@ -147,6 +151,7 @@ gdk_display_open (const gchar *display_name)
   XClassHint *class_hint;
   gulong pid;
   gint i;
+  gint ignore;
 
   xdisplay = XOpenDisplay (display_name);
   if (!xdisplay)
@@ -193,6 +198,21 @@ gdk_display_open (const gchar *display_name)
 
   display_x11->have_render = GDK_UNKNOWN;
 
+#ifdef HAVE_XFIXES
+  if (XFixesQueryExtension (display_x11->xdisplay, 
+                           &display_x11->xfixes_event_base, 
+                           &ignore))
+    {
+      display_x11->have_xfixes = TRUE;
+
+      gdk_x11_register_standard_event_type (display,
+                                           display_x11->xfixes_event_base, 
+                                           XFixesNumberEvents);
+    }
+  else
+#endif
+  display_x11->have_xfixes = FALSE;
+
   if (_gdk_synchronize)
     XSynchronize (display_x11->xdisplay, True);
   
@@ -969,3 +989,63 @@ gdk_notify_startup_complete (void)
 
   g_free (message);
 }
+
+
+/**
+ * gdk_display_supports_selection_notification:
+ * @display: a #GdkDisplay
+ * 
+ * Returns whether #GdkEventOwnerChange events will be 
+ * sent when the owner of a selection changes.
+ * 
+ * Return value: whether #GdkEventOwnerChange events will 
+ *               be sent.
+ *
+ * Since: 2.6
+ **/
+gboolean 
+gdk_display_supports_selection_notification (GdkDisplay *display)
+{
+  GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
+
+  return display_x11->have_xfixes;
+}
+
+/**
+ * gdk_display_request_selection_notification:
+ * @display: a #GdkDisplay
+ * @selection: the #GdkAtom naming the selection for which
+ *             ownership change notification is requested
+ * 
+ * Request #GdkEventOwnerChange events for ownership changes
+ * of the selection named by the given atom.
+ * 
+ * Return value: whether #GdkEventOwnerChange events will 
+ *               be sent.
+ *
+ * Since: 2.6
+ **/
+gboolean gdk_display_request_selection_notification  (GdkDisplay *display,
+                                                     GdkAtom     selection)
+
+{
+#ifdef HAVE_XFIXES
+  GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
+  Atom atom;
+
+  if (display_x11->have_xfixes)
+    {
+      atom = gdk_x11_atom_to_xatom_for_display (display, 
+                                               selection);
+      XFixesSelectSelectionInput (display_x11->xdisplay, 
+                                 display_x11->leader_window,
+                                 atom,
+                                 XFixesSetSelectionOwnerNotifyMask |
+                                 XFixesSelectionWindowDestroyNotifyMask |
+                                 XFixesSelectionClientCloseNotifyMask);
+      return TRUE;
+    }
+  else
+#endif
+    return FALSE;
+}
index 0d3d6838f76bb80f29d891f6ed5389d8d546999c..3ce7d941aa5ca3f64327399e99148151218f7f47 100644 (file)
@@ -78,7 +78,9 @@ struct _GdkDisplayX11
   gboolean use_xshm;
   gboolean have_shm_pixmaps;
   GdkTristate have_render;
-  
+  gboolean have_xfixes;
+  gint xfixes_event_base;
+
   /* Information about current pointer and keyboard grabs held by this
    * client. If gdk_pointer_xgrab_window or gdk_keyboard_xgrab_window
    * window is NULL, then the other associated fields are ignored
index 6f31369af48e0114e53b1253d6d749bb932e4e36..56a29fd8f470d42f768b3cf9528239fa3d04cc5b 100644 (file)
 #include <X11/XKBlib.h>
 #endif
 
+#ifdef HAVE_XFIXES
+#include <X11/extensions/Xfixes.h>
+#endif
+
 #include <X11/Xatom.h>
 
 typedef struct _GdkIOClosure GdkIOClosure;
@@ -1954,6 +1958,24 @@ gdk_event_translate (GdkDisplay *display,
            }
        }
       else
+#endif
+#ifdef HAVE_XFIXES
+      if (xevent->type - display_x11->xfixes_event_base == XFixesSelectionNotify)
+       {
+         XFixesSelectionNotifyEvent *selection_notify = (XFixesSelectionNotifyEvent *)xevent;
+         event->owner_change.type = GDK_OWNER_CHANGE;
+         event->owner_change.window = window;
+         event->owner_change.owner = selection_notify->owner;
+         event->owner_change.reason = selection_notify->subtype;
+         event->owner_change.selection = 
+           gdk_x11_xatom_to_atom_for_display (display, 
+                                              selection_notify->selection);
+         event->owner_change.time = selection_notify->timestamp;
+         event->owner_change.selection_time = selection_notify->selection_timestamp;
+
+         return_val = TRUE;
+       }
+      else
 #endif
        {
          /* something else - (e.g., a Xinput event) */
index 107b40d6978d6ceccec22122e8f86fa8a02c2bcb..fbaafafed193ca2b1f02209d98ea7b3c0e5a14a8 100644 (file)
@@ -25,6 +25,7 @@
 #include "gtkclipboard.h"
 #include "gtkinvisible.h"
 #include "gtkmain.h"
+#include "gtkmarshalers.h"
 
 #ifdef GDK_WINDOWING_X11
 #include "x11/gdkx.h"
 #include "win32/gdkwin32.h"
 #endif
 
+enum {
+  OWNER_CHANGE,
+  LAST_SIGNAL
+};
+
 typedef struct _GtkClipboardClass GtkClipboardClass;
 
 typedef struct _RequestContentsInfo RequestContentsInfo;
@@ -60,6 +66,9 @@ struct _GtkClipboard
 struct _GtkClipboardClass
 {
   GObjectClass parent_class;
+
+  void (*owner_change) (GtkClipboard        *clipboard,
+                       GdkEventOwnerChange *event);
 };
 
 struct _RequestContentsInfo
@@ -83,11 +92,13 @@ struct _RequestTargetsInfo
 static void gtk_clipboard_class_init (GtkClipboardClass *class);
 static void gtk_clipboard_finalize   (GObject           *object);
 
-static void clipboard_unset    (GtkClipboard     *clipboard);
-static void selection_received (GtkWidget        *widget,
-                               GtkSelectionData *selection_data,
-                               guint             time);
-
+static void clipboard_unset          (GtkClipboard      *clipboard);
+static void selection_received       (GtkWidget         *widget,
+                                     GtkSelectionData  *selection_data,
+                                     guint              time);
+static GtkClipboard *clipboard_peek  (GdkDisplay        *display,
+                                     GdkAtom            selection,
+                                     gboolean           only_if_exists);
 enum {
   TARGET_STRING,
   TARGET_TEXT,
@@ -102,6 +113,7 @@ static const gchar clipboards_owned_key[] = "gtk-clipboards-owned";
 static GQuark clipboards_owned_key_id = 0;
 
 static GObjectClass *parent_class;
+static guint         clipboard_signals[LAST_SIGNAL] = { 0 };
 
 GType
 gtk_clipboard_get_type (void)
@@ -138,10 +150,22 @@ gtk_clipboard_class_init (GtkClipboardClass *class)
   parent_class = g_type_class_peek_parent (class);
   
   gobject_class->finalize = gtk_clipboard_finalize;
+
+  class->owner_change = NULL;
+
+  clipboard_signals[OWNER_CHANGE] =
+    g_signal_new ("owner_change",
+                 G_TYPE_FROM_CLASS (gobject_class),
+                 G_SIGNAL_RUN_FIRST,
+                 G_STRUCT_OFFSET (GtkClipboardClass, owner_change),
+                 NULL, NULL,
+                 _gtk_marshal_VOID__BOXED,
+                 G_TYPE_NONE, 1,
+                 GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
 }
 
 static void
-gtk_clipboard_finalize   (GObject *object)
+gtk_clipboard_finalize (GObject *object)
 {
   clipboard_unset (GTK_CLIPBOARD (object));
 
@@ -204,44 +228,16 @@ clipboard_display_closed (GdkDisplay   *display,
  * Since: 2.2
  **/
 GtkClipboard *
-gtk_clipboard_get_for_display (GdkDisplay *display, GdkAtom selection)
+gtk_clipboard_get_for_display (GdkDisplay *display, 
+                              GdkAtom     selection)
 {
-  GtkClipboard *clipboard = NULL;
-  GSList *clipboards;
-  GSList *tmp_list;
-
   g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
   g_return_val_if_fail (!display->closed, NULL);
 
-  if (selection == GDK_NONE)
-    selection = GDK_SELECTION_CLIPBOARD;
-
-  clipboards = g_object_get_data (G_OBJECT (display), "gtk-clipboard-list");
-
-  tmp_list = clipboards;
-  while (tmp_list)
-    {
-      clipboard = tmp_list->data;
-      if (clipboard->selection == selection)
-       break;
-
-      tmp_list = tmp_list->next;
-    }
-
-  if (!tmp_list)
-    {
-      clipboard = g_object_new (GTK_TYPE_CLIPBOARD, NULL);
-      clipboard->selection = selection;
-      clipboard->display = display;
-      clipboards = g_slist_prepend (clipboards, clipboard);
-      g_object_set_data (G_OBJECT (display), "gtk-clipboard-list", clipboards);
-      g_signal_connect (display, "closed",
-                       G_CALLBACK (clipboard_display_closed), clipboard);
-    }
-  
-  return clipboard;
+  return clipboard_peek (display, selection, FALSE);
 }
 
+
 /**
  * gtk_clipboard_get():
  * @selection: a #GdkAtom which identifies the clipboard
@@ -1108,3 +1104,66 @@ gtk_clipboard_wait_for_targets (GtkClipboard  *clipboard,
 
   return result;
 }
+
+static GtkClipboard *
+clipboard_peek (GdkDisplay *display, 
+               GdkAtom     selection,
+               gboolean    only_if_exists)
+{
+  GtkClipboard *clipboard = NULL;
+  GSList *clipboards;
+  GSList *tmp_list;
+
+  if (selection == GDK_NONE)
+    selection = GDK_SELECTION_CLIPBOARD;
+
+  clipboards = g_object_get_data (G_OBJECT (display), "gtk-clipboard-list");
+
+  tmp_list = clipboards;
+  while (tmp_list)
+    {
+      clipboard = tmp_list->data;
+      if (clipboard->selection == selection)
+       break;
+
+      tmp_list = tmp_list->next;
+    }
+
+  if (!tmp_list && !only_if_exists)
+    {
+      clipboard = g_object_new (GTK_TYPE_CLIPBOARD, NULL);
+      clipboard->selection = selection;
+      clipboard->display = display;
+      clipboards = g_slist_prepend (clipboards, clipboard);
+      g_object_set_data (G_OBJECT (display), "gtk-clipboard-list", clipboards);
+      g_signal_connect (display, "closed",
+                       G_CALLBACK (clipboard_display_closed), clipboard);
+      gdk_display_request_selection_notification (display, selection);
+    }
+  
+  return clipboard;
+}
+
+
+/**
+ * _gtk_clipboard_handle_event:
+ * @event: a owner change event
+ * 
+ * Emits the ::owner_change signal on the appropriate @clipboard.
+ *
+ * Since: 2.6
+ **/
+void 
+_gtk_clipboard_handle_event (GdkEventOwnerChange *event)
+{
+  GdkDisplay *display;
+  GtkClipboard *clipboard;
+  
+  display = gdk_drawable_get_display (event->window);
+  clipboard = clipboard_peek (display, event->selection, TRUE);
+      
+  if (clipboard)
+    g_signal_emit (clipboard, 
+                  clipboard_signals[OWNER_CHANGE], 0, event, NULL);
+}
+
index 3d2268393ad35b14221fcd57a1d34695353d6a7d..d706567e5fd8407d7ef30ce37bf854c67abe673d 100644 (file)
@@ -104,6 +104,9 @@ gboolean gtk_clipboard_wait_for_targets (GtkClipboard  *clipboard,
                                         GdkAtom      **targets,
                                         gint          *n_targets);
 
+/* private */
+void     _gtk_clipboard_handle_event    (GdkEventOwnerChange *event);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
index 9b301dbfc1a82a17d396267f8bc4f2a190103b3a..d75ff7248db3f419f2263a0c5794ad5ff3505a92 100644 (file)
@@ -1438,6 +1438,12 @@ gtk_main_do_event (GdkEvent *event)
       return;
     }
 
+  if (event->type == GDK_OWNER_CHANGE)
+    {
+      _gtk_clipboard_handle_event (&event->owner_change);
+      return;
+    }
+
   /* Find the widget which got the event. We store the widget
    *  in the user_data field of GdkWindow's.
    *  Ignore the event if we don't have a widget for it, except